# VideoQualityGenerator_Enhanced.ps1
# 视频质量批量生成器 - 增强版本
# 支持保持宽高比、批量处理、更多编码选项等

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# 检查FFmpeg
function Test-FFmpeg {
    try {
        $null = & ffmpeg -version 2>$null
        return $true
    } catch {
        return $false
    }
}

# 获取视频信息
function Get-VideoInfo {
    param([string]$FilePath)
    try {
        $output = & ffprobe -v quiet -print_format json -show_format -show_streams $FilePath 2>$null | ConvertFrom-Json
        $videoStream = $output.streams | Where-Object { $_.codec_type -eq "video" } | Select-Object -First 1
        return @{
            Width = [int]$videoStream.width
            Height = [int]$videoStream.height
            Duration = [double]$output.format.duration
            AspectRatio = [double]$videoStream.width / [double]$videoStream.height
            IsVertical = [int]$videoStream.height -gt [int]$videoStream.width
        }
    } catch {
        return $null
    }
}

# 创建主窗体
$form = New-Object System.Windows.Forms.Form
$form.Text = "视频质量批量生成器 - 增强版"
$form.Size = New-Object System.Drawing.Size(700, 650)
$form.StartPosition = "CenterScreen"
$form.FormBorderStyle = "FixedDialog"
$form.MaximizeBox = $false

# 检查FFmpeg
if (-not (Test-FFmpeg)) {
    [System.Windows.Forms.MessageBox]::Show(
        "未检测到FFmpeg！`n`n请先安装FFmpeg并将其添加到系统PATH中。`n下载地址: https://ffmpeg.org/download.html",
        "错误",
        [System.Windows.Forms.MessageBoxButtons]::OK,
        [System.Windows.Forms.MessageBoxIcon]::Error
    )
    exit
}

# 标题标签
$titleLabel = New-Object System.Windows.Forms.Label
$titleLabel.Location = New-Object System.Drawing.Point(20, 20)
$titleLabel.Size = New-Object System.Drawing.Size(660, 30)
$titleLabel.Text = "视频质量批量生成器 - 增强版"
$titleLabel.Font = New-Object System.Drawing.Font("Microsoft YaHei", 16, [System.Drawing.FontStyle]::Bold)
$titleLabel.TextAlign = "MiddleCenter"

# 模式选择
$modeGroupBox = New-Object System.Windows.Forms.GroupBox
$modeGroupBox.Location = New-Object System.Drawing.Point(20, 60)
$modeGroupBox.Size = New-Object System.Drawing.Size(660, 50)
$modeGroupBox.Text = "处理模式"

$singleFileRadio = New-Object System.Windows.Forms.RadioButton
$singleFileRadio.Location = New-Object System.Drawing.Point(20, 20)
$singleFileRadio.Size = New-Object System.Drawing.Size(150, 20)
$singleFileRadio.Text = "单文件处理"
$singleFileRadio.Checked = $true

$batchFileRadio = New-Object System.Windows.Forms.RadioButton
$batchFileRadio.Location = New-Object System.Drawing.Point(200, 20)
$batchFileRadio.Size = New-Object System.Drawing.Size(150, 20)
$batchFileRadio.Text = "批量处理"

$modeGroupBox.Controls.AddRange(@($singleFileRadio, $batchFileRadio))

# 输入选择
$inputLabel = New-Object System.Windows.Forms.Label
$inputLabel.Location = New-Object System.Drawing.Point(20, 130)
$inputLabel.Size = New-Object System.Drawing.Size(100, 23)
$inputLabel.Text = "选择输入:"

$inputTextBox = New-Object System.Windows.Forms.TextBox
$inputTextBox.Location = New-Object System.Drawing.Point(120, 130)
$inputTextBox.Size = New-Object System.Drawing.Size(440, 23)
$inputTextBox.ReadOnly = $true

$browseButton = New-Object System.Windows.Forms.Button
$browseButton.Location = New-Object System.Drawing.Point(570, 129)
$browseButton.Size = New-Object System.Drawing.Size(90, 25)
$browseButton.Text = "浏览..."

# 输出目录选择
$outputLabel = New-Object System.Windows.Forms.Label
$outputLabel.Location = New-Object System.Drawing.Point(20, 170)
$outputLabel.Size = New-Object System.Drawing.Size(100, 23)
$outputLabel.Text = "输出目录:"

$outputTextBox = New-Object System.Windows.Forms.TextBox
$outputTextBox.Location = New-Object System.Drawing.Point(120, 170)
$outputTextBox.Size = New-Object System.Drawing.Size(440, 23)
$outputTextBox.ReadOnly = $true

$outputBrowseButton = New-Object System.Windows.Forms.Button
$outputBrowseButton.Location = New-Object System.Drawing.Point(570, 169)
$outputBrowseButton.Size = New-Object System.Drawing.Size(90, 25)
$outputBrowseButton.Text = "浏览..."

# 质量和缩放设置
$qualityGroupBox = New-Object System.Windows.Forms.GroupBox
$qualityGroupBox.Location = New-Object System.Drawing.Point(20, 210)
$qualityGroupBox.Size = New-Object System.Drawing.Size(660, 180)
$qualityGroupBox.Text = "质量设置和缩放选项"

# 左侧质量选择
$quality240p = New-Object System.Windows.Forms.CheckBox
$quality240p.Location = New-Object System.Drawing.Point(20, 30)
$quality240p.Size = New-Object System.Drawing.Size(150, 20)
$quality240p.Text = "240p (426x240)"

$quality360p = New-Object System.Windows.Forms.CheckBox
$quality360p.Location = New-Object System.Drawing.Point(20, 55)
$quality360p.Size = New-Object System.Drawing.Size(150, 20)
$quality360p.Text = "360p (640x360)"
$quality360p.Checked = $true

$quality480p = New-Object System.Windows.Forms.CheckBox
$quality480p.Location = New-Object System.Drawing.Point(20, 80)
$quality480p.Size = New-Object System.Drawing.Size(150, 20)
$quality480p.Text = "480p (854x480)"
$quality480p.Checked = $true

$quality720p = New-Object System.Windows.Forms.CheckBox
$quality720p.Location = New-Object System.Drawing.Point(20, 105)
$quality720p.Size = New-Object System.Drawing.Size(150, 20)
$quality720p.Text = "720p (1280x720)"
$quality720p.Checked = $true

$quality1080p = New-Object System.Windows.Forms.CheckBox
$quality1080p.Location = New-Object System.Drawing.Point(20, 130)
$quality1080p.Size = New-Object System.Drawing.Size(150, 20)
$quality1080p.Text = "1080p (1920x1080)"

# 缩放模式选择
$scaleLabel = New-Object System.Windows.Forms.Label
$scaleLabel.Location = New-Object System.Drawing.Point(200, 30)
$scaleLabel.Size = New-Object System.Drawing.Size(80, 20)
$scaleLabel.Text = "缩放模式:"

$scaleComboBox = New-Object System.Windows.Forms.ComboBox
$scaleComboBox.Location = New-Object System.Drawing.Point(280, 28)
$scaleComboBox.Size = New-Object System.Drawing.Size(180, 23)
$scaleComboBox.DropDownStyle = "DropDownList"
$scaleComboBox.Items.AddRange(@(
    "智能适应 (推荐)",
    "适应内部 (添加黑边)",
    "填充整个画面 (可能裁切)",
    "强制拉伸 (可能变形)"
))
$scaleComboBox.SelectedIndex = 0

# 视频编码设置
$codecLabel = New-Object System.Windows.Forms.Label
$codecLabel.Location = New-Object System.Drawing.Point(200, 60)
$codecLabel.Size = New-Object System.Drawing.Size(80, 20)
$codecLabel.Text = "视频编码:"

$codecComboBox = New-Object System.Windows.Forms.ComboBox
$codecComboBox.Location = New-Object System.Drawing.Point(280, 58)
$codecComboBox.Size = New-Object System.Drawing.Size(180, 23)
$codecComboBox.DropDownStyle = "DropDownList"
$codecComboBox.Items.AddRange(@("H.264 (推荐)", "H.265/HEVC", "VP9"))
$codecComboBox.SelectedIndex = 0

# 编码预设
$presetLabel = New-Object System.Windows.Forms.Label
$presetLabel.Location = New-Object System.Drawing.Point(200, 90)
$presetLabel.Size = New-Object System.Drawing.Size(80, 20)
$presetLabel.Text = "编码速度:"

$presetComboBox = New-Object System.Windows.Forms.ComboBox
$presetComboBox.Location = New-Object System.Drawing.Point(280, 88)
$presetComboBox.Size = New-Object System.Drawing.Size(180, 23)
$presetComboBox.DropDownStyle = "DropDownList"
$presetComboBox.Items.AddRange(@("ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow"))
$presetComboBox.SelectedIndex = 5

# CRF质量设置
$crfLabel = New-Object System.Windows.Forms.Label
$crfLabel.Location = New-Object System.Drawing.Point(200, 120)
$crfLabel.Size = New-Object System.Drawing.Size(80, 20)
$crfLabel.Text = "质量 (CRF):"

$crfTrackBar = New-Object System.Windows.Forms.TrackBar
$crfTrackBar.Location = New-Object System.Drawing.Point(280, 118)
$crfTrackBar.Size = New-Object System.Drawing.Size(120, 25)
$crfTrackBar.Minimum = 18
$crfTrackBar.Maximum = 28
$crfTrackBar.Value = 23
$crfTrackBar.TickFrequency = 2

$crfValueLabel = New-Object System.Windows.Forms.Label
$crfValueLabel.Location = New-Object System.Drawing.Point(410, 120)
$crfValueLabel.Size = New-Object System.Drawing.Size(40, 20)
$crfValueLabel.Text = "23"

# 高级选项
$advancedCheckBox = New-Object System.Windows.Forms.CheckBox
$advancedCheckBox.Location = New-Object System.Drawing.Point(480, 30)
$advancedCheckBox.Size = New-Object System.Drawing.Size(150, 20)
$advancedCheckBox.Text = "启用硬件加速"

$denoiseCheckBox = New-Object System.Windows.Forms.CheckBox
$denoiseCheckBox.Location = New-Object System.Drawing.Point(480, 55)
$denoiseCheckBox.Size = New-Object System.Drawing.Size(150, 20)
$denoiseCheckBox.Text = "启用降噪"

$stabilizeCheckBox = New-Object System.Windows.Forms.CheckBox
$stabilizeCheckBox.Location = New-Object System.Drawing.Point(480, 80)
$stabilizeCheckBox.Size = New-Object System.Drawing.Size(150, 20)
$stabilizeCheckBox.Text = "视频防抖 (慢)"

$qualityGroupBox.Controls.AddRange(@(
    $quality240p, $quality360p, $quality480p, $quality720p, $quality1080p,
    $scaleLabel, $scaleComboBox,
    $codecLabel, $codecComboBox,
    $presetLabel, $presetComboBox,
    $crfLabel, $crfTrackBar, $crfValueLabel,
    $advancedCheckBox, $denoiseCheckBox, $stabilizeCheckBox
))

# 视频信息显示
$infoGroupBox = New-Object System.Windows.Forms.GroupBox
$infoGroupBox.Location = New-Object System.Drawing.Point(20, 400)
$infoGroupBox.Size = New-Object System.Drawing.Size(660, 60)
$infoGroupBox.Text = "视频信息"

$infoLabel = New-Object System.Windows.Forms.Label
$infoLabel.Location = New-Object System.Drawing.Point(10, 20)
$infoLabel.Size = New-Object System.Drawing.Size(640, 35)
$infoLabel.Text = "请选择视频文件以查看信息"

$infoGroupBox.Controls.Add($infoLabel)

# 进度条
$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Location = New-Object System.Drawing.Point(20, 480)
$progressBar.Size = New-Object System.Drawing.Size(660, 23)

# 状态标签
$statusLabel = New-Object System.Windows.Forms.Label
$statusLabel.Location = New-Object System.Drawing.Point(20, 510)
$statusLabel.Size = New-Object System.Drawing.Size(660, 40)
$statusLabel.Text = "就绪"

# 生成按钮
$generateButton = New-Object System.Windows.Forms.Button
$generateButton.Location = New-Object System.Drawing.Point(250, 570)
$generateButton.Size = New-Object System.Drawing.Size(200, 40)
$generateButton.Text = "开始生成"
$generateButton.Font = New-Object System.Drawing.Font("Microsoft YaHei", 12, [System.Drawing.FontStyle]::Bold)
$generateButton.BackColor = [System.Drawing.Color]::FromArgb(0, 122, 204)
$generateButton.ForeColor = [System.Drawing.Color]::White
$generateButton.FlatStyle = "Flat"

# 事件处理
$crfTrackBar.Add_ValueChanged({
    $crfValueLabel.Text = $crfTrackBar.Value.ToString()
})

$singleFileRadio.Add_CheckedChanged({
    if ($singleFileRadio.Checked) {
        $inputLabel.Text = "选择视频文件:"
        $browseButton.Text = "浏览..."
    }
})

$batchFileRadio.Add_CheckedChanged({
    if ($batchFileRadio.Checked) {
        $inputLabel.Text = "选择文件夹:"
        $browseButton.Text = "选择文件夹"
        $inputTextBox.Text = ""
        $infoLabel.Text = "批量处理模式：将处理选定文件夹中的所有视频文件"
    }
})

$browseButton.Add_Click({
    if ($singleFileRadio.Checked) {
        $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
        $openFileDialog.Filter = "视频文件|*.mp4;*.avi;*.mov;*.mkv;*.flv;*.wmv;*.m4v;*.3gp;*.webm|所有文件|*.*"
        $openFileDialog.Title = "选择视频文件"
        
        if ($openFileDialog.ShowDialog() -eq "OK") {
            $inputTextBox.Text = $openFileDialog.FileName
            
            # 自动设置输出目录
            $videoDir = Split-Path $openFileDialog.FileName -Parent
            $outputTextBox.Text = Join-Path $videoDir "output"
            
            # 显示视频信息
            $videoInfo = Get-VideoInfo -FilePath $openFileDialog.FileName
            if ($videoInfo) {
                $orientation = if ($videoInfo.IsVertical) { "竖屏" } else { "横屏" }
                $duration = [TimeSpan]::FromSeconds($videoInfo.Duration).ToString("mm\:ss")
                $infoLabel.Text = "分辨率: $($videoInfo.Width)x$($videoInfo.Height) | 宽高比: $([math]::Round($videoInfo.AspectRatio, 2)) | 时长: $duration | 方向: $orientation"
            }
        }
    } else {
        $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
        $folderBrowser.Description = "选择包含视频文件的文件夹"
        
        if ($folderBrowser.ShowDialog() -eq "OK") {
            $inputTextBox.Text = $folderBrowser.SelectedPath
            $outputTextBox.Text = Join-Path $folderBrowser.SelectedPath "output"
            
            # 统计视频文件数量
            $videoFiles = Get-ChildItem -Path $folderBrowser.SelectedPath -Include "*.mp4","*.avi","*.mov","*.mkv","*.flv","*.wmv","*.m4v","*.3gp","*.webm" -Recurse
            $infoLabel.Text = "找到 $($videoFiles.Count) 个视频文件"
        }
    }
})

$outputBrowseButton.Add_Click({
    $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
    $folderBrowser.Description = "选择输出目录"
    
    if ($folderBrowser.ShowDialog() -eq "OK") {
        $outputTextBox.Text = $folderBrowser.SelectedPath
    }
})

# 生成视频函数 - 改进版，支持保持宽高比
function Generate-VideoQualities {
    param (
        [string[]]$InputFiles,
        [string]$OutputDir,
        [hashtable]$QualitySettings,
        [string]$ScaleMode,
        [string]$Codec,
        [string]$Preset,
        [int]$CRF,
        [bool]$HardwareAccel,
        [bool]$Denoise,
        [bool]$Stabilize
    )
    
    # 创建输出目录
    if (-not (Test-Path $OutputDir)) {
        New-Item -Path $OutputDir -ItemType Directory -Force | Out-Null
    }
    
    # 编码器映射
    $codecMap = @{
        "H.264 (推荐)" = "libx264"
        "H.265/HEVC" = "libx265"
        "VP9" = "libvpx-vp9"
    }
    
    $selectedCodec = $codecMap[$Codec]
    
    $totalFiles = $InputFiles.Count
    $currentFile = 0
    
    foreach ($inputFile in $InputFiles) {
        $currentFile++
        $fileName = [System.IO.Path]::GetFileNameWithoutExtension($inputFile)
        $extension = ".mp4"  # 统一使用MP4格式
        
        # 获取原视频信息
        $videoInfo = Get-VideoInfo -FilePath $inputFile
        if (-not $videoInfo) {
            $statusLabel.Text = "无法获取视频信息: $fileName"
            continue
        }
        
        $statusLabel.Text = "正在处理: $fileName ($currentFile/$totalFiles)"
        $form.Refresh()
        
        foreach ($qualityName in $QualitySettings.Keys) {
            $quality = $QualitySettings[$qualityName]
            
            $outputFile = Join-Path $OutputDir "$fileName`_$qualityName$extension"
            
            # 构建FFmpeg过滤器链
            $filters = @()
            
            # 缩放过滤器 - 关键改进：保持宽高比
            switch ($ScaleMode) {
                "智能适应 (推荐)" {
                    # 使用-2确保结果能被2整除，保持宽高比
                    if ($videoInfo.IsVertical) {
                        # 竖屏视频：固定宽度，自动计算高度
                        $filters += "scale=$($quality.Width):-2"
                    } else {
                        # 横屏视频：固定高度，自动计算宽度  
                        $filters += "scale=-2:$($quality.Height)"
                    }
                }
                "适应内部 (添加黑边)" {
                    # 使用force_original_aspect_ratio=decrease配合pad添加黑边
                    $filters += "scale=$($quality.Width):$($quality.Height):force_original_aspect_ratio=decrease,pad=$($quality.Width):$($quality.Height):(ow-iw)/2:(oh-ih)/2:color=black"
                }
                "填充整个画面 (可能裁切)" {
                    # 使用force_original_aspect_ratio=increase配合crop填充画面
                    $filters += "scale=$($quality.Width):$($quality.Height):force_original_aspect_ratio=increase,crop=$($quality.Width):$($quality.Height)"
                }
                "强制拉伸 (可能变形)" {
                    # 直接拉伸到目标尺寸
                    $filters += "scale=$($quality.Width):$($quality.Height)"
                }
            }
            
            # 添加其他滤镜
            if ($Denoise) {
                $filters += "hqdn3d"
            }
            
            if ($Stabilize) {
                $filters += "deshake"
            }
            
            # 构建FFmpeg命令参数
            $ffmpegArgs = @("-i", "`"$inputFile`"")
            
            # 硬件加速
            if ($HardwareAccel) {
                $ffmpegArgs += @("-hwaccel", "auto")
            }
            
            # 视频滤镜
            if ($filters.Count -gt 0) {
                $ffmpegArgs += @("-vf", ($filters -join ","))
            }
            
            # 视频编码设置
            $ffmpegArgs += @(
                "-c:v", $selectedCodec,
                "-preset", $Preset,
                "-crf", $CRF.ToString()
            )
            
            # 音频设置
            $ffmpegArgs += @(
                "-c:a", "aac",
                "-b:a", $quality.AudioBitrate
            )
            
            # 其他设置
            $ffmpegArgs += @(
                "-movflags", "+faststart",
                "-y",
                "`"$outputFile`""
            )
            
            # 执行FFmpeg
            $statusLabel.Text = "正在生成: $fileName - $qualityName"
            $form.Refresh()
            
            $process = Start-Process -FilePath "ffmpeg" -ArgumentList $ffmpegArgs -NoNewWindow -Wait -PassThru
            
            if ($process.ExitCode -ne 0) {
                [System.Windows.Forms.MessageBox]::Show(
                    "生成 $fileName - $qualityName 时出错！",
                    "错误",
                    [System.Windows.Forms.MessageBoxButtons]::OK,
                    [System.Windows.Forms.MessageBoxIcon]::Error
                )
            }
        }
        
        # 更新进度
        $progressBar.Value = [int]($currentFile / $totalFiles * 100)
        $form.Refresh()
    }
    
    $statusLabel.Text = "所有视频处理完成！"
    [System.Windows.Forms.MessageBox]::Show(
        "视频处理完成！`n输出目录: $OutputDir",
        "完成",
        [System.Windows.Forms.MessageBoxButtons]::OK,
        [System.Windows.Forms.MessageBoxIcon]::Information
    )
}

$generateButton.Add_Click({
    # 验证输入
    if ([string]::IsNullOrWhiteSpace($inputTextBox.Text)) {
        [System.Windows.Forms.MessageBox]::Show("请选择输入文件或文件夹！", "提示", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)
        return
    }
    
    if ([string]::IsNullOrWhiteSpace($outputTextBox.Text)) {
        [System.Windows.Forms.MessageBox]::Show("请选择输出目录！", "提示", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)
        return
    }
    
    # 获取选中的质量设置
    $selectedQualities = @{}
    
    if ($quality240p.Checked) {
        $selectedQualities["240p"] = @{ Width = 426; Height = 240; AudioBitrate = "64k" }
    }
    if ($quality360p.Checked) {
        $selectedQualities["360p"] = @{ Width = 640; Height = 360; AudioBitrate = "96k" }
    }
    if ($quality480p.Checked) {
        $selectedQualities["480p"] = @{ Width = 854; Height = 480; AudioBitrate = "128k" }
    }
    if ($quality720p.Checked) {
        $selectedQualities["720p"] = @{ Width = 1280; Height = 720; AudioBitrate = "192k" }
    }
    if ($quality1080p.Checked) {
        $selectedQualities["1080p"] = @{ Width = 1920; Height = 1080; AudioBitrate = "256k" }
    }
    
    if ($selectedQualities.Count -eq 0) {
        [System.Windows.Forms.MessageBox]::Show("请至少选择一个质量版本！", "提示", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)
        return
    }
    
    # 获取输入文件列表
    $inputFiles = @()
    
    if ($singleFileRadio.Checked) {
        $inputFiles = @($inputTextBox.Text)
    } else {
        $inputFiles = Get-ChildItem -Path $inputTextBox.Text -Include "*.mp4","*.avi","*.mov","*.mkv","*.flv","*.wmv","*.m4v","*.3gp","*.webm" -Recurse | ForEach-Object { $_.FullName }
        
        if ($inputFiles.Count -eq 0) {
            [System.Windows.Forms.MessageBox]::Show("在选定文件夹中未找到视频文件！", "提示", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)
            return
        }
    }
    
    # 禁用控件
    $generateButton.Enabled = $false
    $browseButton.Enabled = $false
    $outputBrowseButton.Enabled = $false
    
    try {
        Generate-VideoQualities `
            -InputFiles $inputFiles `
            -OutputDir $outputTextBox.Text `
            -QualitySettings $selectedQualities `
            -ScaleMode $scaleComboBox.SelectedItem `
            -Codec $codecComboBox.SelectedItem `
            -Preset $presetComboBox.SelectedItem `
            -CRF $crfTrackBar.Value `
            -HardwareAccel $advancedCheckBox.Checked `
            -Denoise $denoiseCheckBox.Checked `
            -Stabilize $stabilizeCheckBox.Checked
    } finally {
        # 恢复控件
        $generateButton.Enabled = $true
        $browseButton.Enabled = $true
        $outputBrowseButton.Enabled = $true
        $progressBar.Value = 0
    }
})

# 添加控件到窗体
$form.Controls.AddRange(@(
    $titleLabel,
    $modeGroupBox,
    $inputLabel, $inputTextBox, $browseButton,
    $outputLabel, $outputTextBox, $outputBrowseButton,
    $qualityGroupBox,
    $infoGroupBox,
    $progressBar,
    $statusLabel,
    $generateButton
))

# 显示窗体
[void]$form.ShowDialog()